<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-styles/paper-styles.html">
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../../bower_components/iron-icons/editor-icons.html">

<script src='../../bower_components/moment/min/moment.min.js'></script>
<script src='relative.time.parser.js'></script>

<!--
@demo demo/index.html
@hero hero.svg
-->

<dom-module id="timerange-picker">
    <template>
        <style>
             :host {
                display: flex;
                box-sizing: border-box;
                align-items: center;
                justify-content: center;
                margin-bottom: 4px;
            }

            .flex, .layout.horizontal {
                display: flex;
                flex-direction: row;
            }

            paper-button#currentTimeRangeButton {
                text-transform: none;
            }

            paper-icon-button {
                padding: 0.7em 0.57em;
            }

            paper-icon-button[disabled] {
                opacity: 0.32;
            }

            paper-button[disabled] {
                background-color: #ccc !important;
            }

            .time-input paper-icon-button {
                align-self: flex-end;
            }

            .time-input {
                vertical-align: baseline;
            }

            .buttons {
                justify-content: flex-end;
            }

            #timerange {
                margin-right: 16px;
            }

            #quickrange {
                margin: 0 16px 32px 16px;
            }

            paper-dialog h3 {
                margin-top: 0;
                margin-bottom: 0;
            }

            hr {
                margin: 0;
                opacity: 0.54;
            }

            paper-item {
                padding: 4px;
                font-size: 14px;
                min-height: auto;
                cursor: pointer;
            }

            paper-icon-button,
            paper-icon-button {
                display: block;
            }

            .pick-buttons {
                display: flex;
                justify-content: flex-end;
            }

        </style>

        <paper-icon-button on-tap="moveTimeRangeBack" icon="icons:chevron-left"></paper-icon-button>
        <paper-button id="currentTimeRangeButton" toggles active="{{isMainDialogOpen}}">[[durationText]]</paper-button>
        <paper-icon-button id="plusButton" disabled$="[[!_isFwdAllowed(to)]]" on-tap="moveTimeRangeFwd" icon="icons:chevron-right"></paper-icon-button>

        <paper-dialog opened="{{isMainDialogOpen}}" id="dialog" modal class="paper-time-picker-dialog">
            <div class="layout horizontal">
                <div id="timerange">
                    <h3>Time Range</h3>
                    <div class="layout horizontal time-input">
                        <paper-input class="flex" id="to" label="From [[_computeText(selectedFrom)]]" value="{{selectedFrom}}"></paper-input>
                        <paper-icon-button class="from" toggles active="{{isFromDialogOpen}}" icon="editor:insert-invitation"></paper-icon-button>
                    </div>
                    <div class="layout horizontal time-input">
                        <paper-input class="flex" id="to" label="To [[_computeText(selectedTo)]]" value="{{selectedTo}}"></paper-input>
                        <paper-icon-button class="to" toggles active="{{isToDialogOpen}}" icon="editor:insert-invitation"></paper-icon-button>
                    </div>
                    <paper-dropdown-menu id="refreshIntervalMenu" disabled$="[[!_isRefreshAllowed(selectedTo)]]" label="refresh" placeholder="off">
                        <paper-listbox slot="dropdown-content" class="dropdown-content" selected="{{selectedRefreshInterval}}" attr-for-selected="data-value">
                            <paper-item data-value=0>off</paper-item>
                            <paper-item data-value=10000>every 10sec</paper-item>
                            <paper-item data-value=60000>every 1min</paper-item>
                            <paper-item data-value=600000>every 10min</paper-item>
                        </paper-listbox>
                    </paper-dropdown-menu>
                </div>
                <div id="quickrange">
                    <h3>Quick Ranges</h3>
                    <div id="listbox" role="listbox">
                        <template is="dom-repeat" items="[[quickRanges]]" as="item">
                            <paper-item id="range" class$="range-button" from$="[[item.from]]" to$="[[item.to]]" type$="[[item.type]]" on-tap="selectQuickRange">[[item.text]]</paper-item>
                        </template>
                    </div>
                </div>
            </div>
            <hr/>
            <div class="layout horizontal buttons">
                <paper-button dialog-dismiss>Cancel</paper-button>
                <paper-button dialog-confirm on-tap="applyRange">Apply</paper-button>
            </div>
        </paper-dialog>

        <paper-dialog id="datetime" opened="{{isFromDialogOpen}}">
            <h2>Select start of time range</h2>
            <paper-input id="datetimeFrom" type="datetime-local" label="[[_computeText(temporaryFrom)]]" value="{{temporaryFrom}}" max="[[_getNow()]]" auto-validate></paper-input>
            <div class="pick-buttons">
                <paper-button dialog-dismiss>Cancel</paper-button>
                <paper-button dialog-confirm on-tap="applyFrom" disabled="[[!_isValid(temporaryFrom)]]">Apply</paper-button>
            </div>
        </paper-dialog>

        <paper-dialog id="datetime" opened="{{isToDialogOpen}}">
            <h2>Select end of time range</h2>
            <paper-input id="datetimeTo" type="datetime-local" label="[[_computeText(temporaryTo)]]" value="{{temporaryTo}}" max="[[_getNow()]]" auto-validate></paper-input>
            <div class="pick-buttons">
                <paper-button dialog-dismiss>Cancel</paper-button>
                <paper-button dialog-confirm on-tap="applyTo" disabled="[[!_isValid(temporaryTo)]]">Apply</paper-button>
            </div>
        </paper-dialog>
    </template>
    <script>
        Polymer({
            is: 'timerange-picker',

            properties: {
                from: {
                    type: String,
                    notify: true,
                    value: '',
                    observer: '_fromUpdated'
                },
                to: {
                    type: String,
                    notify: true,
                    value: '',
                    observer: '_toUpdated'
                },
                refreshInterval: {
                    type: Number,
                    notify: true,
                    value: 0,
                    observer: '_refreshIntervalUpdated'
                },
                selectedFrom: {
                    type: String,
                },
                selectedTo: {
                    type: String,
                },
                temporaryFrom: {
                    type: String,
                },
                temporaryTo: {
                    type: String,
                },
                selectedRefreshInterval: {
                    type: Number,
                    value: 0
                },
                durationText: {
                    type: String,
                    computed: '_computeDurationText(from, to)'
                },
                timeRangeDurationInMinutes: {
                    type: Number,
                    notify: true,
                    computed: '_computetimeRangeDurationInMinutes(from, to)'
                },
                isMainDialogOpen: {
                    type: Boolean
                },
                isFromDialogOpen:  {
                    type: Boolean
                },
                isToDialogOpen:  {
                    type: Boolean
                },
                quickRanges: {
                    type: Array,
                    value: function() {
                        return [{
                            from: 10,
                            to: "now",
                            type: "minutes",
                            text: "Last 10 minutes",
                            refreshInterval: 10000
                        }, {
                            from: 1,
                            to: "now",
                            type: "hour",
                            text: "Last 1 hour",
                            refreshInterval: 60000
                        }, {
                            from: 6,
                            to: "now",
                            type: "hours",
                            text: "Last 6 hours",
                            refreshInterval: 600000
                        }, {
                            from: 7,
                            to: "now",
                            type: "days",
                            text: "Last 7 days",
                            refreshInterval: 600000
                        }, {
                            from: 30,
                            to: "now",
                            type: "days",
                            text: "Last 30 days",
                            refreshInterval: 600000
                        }, {
                            from: 1,
                            to: "now",
                            type: "year",
                            text: "Last 1 year",
                            refreshInterval: 600000
                        }];
                    }
                }
            },

            observers: [
                '_isFromDialogOpenChanged(isFromDialogOpen)',
                '_isToDialogOpenChanged(isToDialogOpen)'
            ],

            attached: function() {
                // `attached` fires once the element and its parents have been inserted
                // into a document.
                //
                // This is a good place to perform any work related to your element's
                // visual state or active behavior (measuring sizes, beginning animations,
                // loading resources, etc).
                moment = initializeMomentRelative(moment);
                console.debug('timerange-picker attached');
            },

            detached: function() {
                // The analog to `attached`, `detached` fires when the element has been
                // removed from a document.
                //
                // Use this to clean up anything you did in `attached`.
                console.debug('timerange-picker detached');
            },

            _getNow: function() {
                console.log('_getNow', moment().format('MM/DD/YYYYTHH:mm'));
                return moment().format('MM/DD/YYYYTHH:mm');
            },

            _computeText: function(date) {
                if (!date) {
                    return 'Select a date.';
                } else if (typeof date == 'string' && (date.trim().startsWith('now') || date.trim().startsWith('-'))) {
                    return moment.utc(date).local().relativeTime(date) && moment.utc(date).local().relativeTime(date).fromNow();
                } else if (!moment(date).isValid()) {
                    return '';
                } else {
                    return moment.utc(date).local().fromNow();
                }
            },

            _isFromDialogOpenChanged: function(isFromDialogOpen) {
                // console.log('isFromDialogOpen', isFromDialogOpen);
                if (isFromDialogOpen) { //opened dialog
                    this.set('temporaryFrom', this.selectedFrom.slice(0));
                } 
            },

            _isToDialogOpenChanged: function(isToDialogOpen) {
                // console.log('isFromDialogOpen', isToDialogOpen);
                if (isToDialogOpen) { //opened dialog
                    this.set('temporaryTo', this.selectedTo.slice(0));
                }
            },

            _isRefreshAllowed: function(selectedTo) {
                if (!selectedTo || (typeof selectedTo == "string" && selectedTo.indexOf('now') == -1)) {
                    return false;
                } else {
                    return true;
                }
            },

            _isFwdAllowed: function(to) {
                if (typeof to == "string" && to.startsWith("now")) {
                    return false;
                }
                return true;
            },

            _fromUpdated: function() {
                if (typeof this.from == 'string' && (this.from.trim().startsWith('now') || this.from.trim().startsWith('-'))) {
                    this.selectedFrom = this.from;
                } else
                    this.selectedFrom = this._computeMoment(this.from).format('MM/DD/YYYY HH:mm');
            },

            _toUpdated: function() {
                if (typeof this.to == 'string' && (this.to.trim().startsWith('now') || this.to.trim().startsWith('-'))) {
                    this.selectedTo = this.to;
                } else {
                    this.selectedTo = this._computeMoment(this.to).format('MM/DD/YYYY HH:mm');
                }
            },

            _refreshIntervalUpdated: function() {
                this.selectedRefreshInterval = this.refreshInterval;
            },

            _computeDurationText: function(from, to) {
                if (!from) {
                    return;
                }
                var momentFrom = this._computeMoment(from),
                    momentTo;
                if (!to) {
                    momentTo = this._computeMoment("now");
                } else {
                    momentTo = this._computeMoment(to);
                }
                if (typeof this.to == "string" && this.to.trim().startsWith("now")){
                    return ("Last " + momentFrom.fromNow(true)).replace(" an ", " ").replace(" a ", " ");
                }
                return momentFrom.format('MM/DD/YYYY HH:mm') + " - " + momentTo.format('MM/DD/YYYY HH:mm');
            },

            _computeMoment: function(m) {
                // relative dates start with now or -
                if (typeof m == 'string' && (m.trim().startsWith('now') || m.trim().startsWith('-'))) {
                    return moment().relativeTime(m);
                } else {
                    return typeof m == "number" ? moment(m*1000) : moment(m) ;
                }
            },

            _computetimeRangeDurationInMinutes: function(from, to){
                var momentFrom = this._computeMoment(from),
                    momentTo = this._computeMoment(to);
                return Math.round((momentTo-momentFrom)/60000);
            },

            applyFrom: function() {
                // console.log('applyFrom', this.temporaryFrom, moment(this.temporaryFrom).utc().format('MM/DD/YYYY HH:mm:ss'))
                this.set('selectedFrom', moment(this.temporaryFrom).utc().format('MM/DD/YYYY HH:mm:ss'));
            },

            applyTo: function() {
                // console.log('applyTo', this.temporaryTo, moment(this.temporaryTo).utc().format('MM/DD/YYYY HH:mm:ss'))
                this.set('selectedTo', moment(this.temporaryTo).utc().format('MM/DD/YYYY HH:mm:ss'));
            },

            selectQuickRange: function(e) {
                var el = e.target;
                var diff = 0;
                var from = e.model.item.from;
                var to = e.model.item.to;
                var val = e.model.item.type;

                var newDate = new Date();
                switch (val) {
                    case "days":
                        this.selectedFrom = -from + "d";
                        break;
                    case "hour":
                    case "hours":
                        this.selectedFrom = -from + "h";
                        break;
                    case "year":
                        this.selectedFrom = -from + "y";
                        break;
                    case "minutes":
                        this.selectedFrom = -from + "min";
                        break;
                }
                this.selectedRefreshInterval = Number(e.model.item.refreshInterval);
                this.selectedTo = "now";
            },

            moveTimeRangeBack: function() {
                var momentFrom = this._computeMoment(this.from),
                    momentTo = this._computeMoment(this.to);
                // we're setting "to" to undefined to avoid triggering the observers until both "to" and "from" have final values
                // this.to = undefined;
                var newTo = moment(momentTo - this.timeRangeDurationInMinutes * 60000).unix();
                this.from = moment(momentFrom - this.timeRangeDurationInMinutes * 60000).unix();
                this.to = newTo;
            },

            moveTimeRangeFwd: function() {
                var momentFrom = this._computeMoment(this.from),
                    momentTo = this._computeMoment(this.to);
                // we're setting "to" to undefined to avoid triggering the observers until both "to" and "from" have final values
                if (moment(momentTo + this.timeRangeDurationInMinutes * 60000) > moment()){
                    // this.to = undefined;
                    var newTo = 'now';
                    this.from = moment(moment() - this.timeRangeDurationInMinutes * 60000).unix();
                    this.to = newTo;
                } else {
                    var newTo = moment(momentTo + this.timeRangeDurationInMinutes * 60000).unix();
                    // this.to = undefined;
                    this.from = moment(momentFrom + this.timeRangeDurationInMinutes * 60000).unix();
                    this.to = newTo;
                }
            },

            applyRange: function() {
                if (this.selectedRefreshInterval != this.refreshInterval) {
                    this.refreshInterval = Number(this.selectedRefreshInterval);
                }
                var from, to;
                if (typeof this.selectedTo === "number") {
                    var df = new Date(this.selectedFrom);
                    var dt = new Date(this.selectedTo);
                    this.to = dt.getTime() / 1000;
                    this.from = df.getTime() / 1000;
                } else {
                    if (this.selectedTo.indexOf('/') > -1) {
                        this.to = moment(this.selectedTo).unix();
                    } else {
                        this.to = this.selectedTo;
                    }

                    if (this.selectedFrom.indexOf('/') > -1) {
                        this.from = moment(this.selectedFrom).unix();
                    } else {
                        this.from = this.selectedFrom;
                    }
                }
            },
            _isValid: function(date) {
                // console.log('isValid', date, moment(date).isValid());
                return moment(date).isValid();
            }
        });
    </script>
</dom-module>
